import { camelCase, snakeCase, mapKeys, isPlainObject } from 'lodash'

export enum ObjectMapperStyle {
  // 驼峰风格
  CamelCase,
  // 下划线风格
  SnakeCase,
}

export class ObjectMapper {
  /**
   * 数据转换
   * @param data 要转换的数据
   * @param style 转换风格，默认为驼峰风格
   * @returns 转换后的数据
   */
  static mapObject<T>(data: unknown, style = ObjectMapperStyle.CamelCase): T | null {
    // 如果传入数据为null，则返回null
    if (data == null) {
      return null
    }

    // 如果传入数据为数组，则对数组中的每个元素进行映射操作
    if (Array.isArray(data)) {
      return data.map(item => this.mapObject(item, style)) as T
    }

    // 如果传入数据为对象，则将对象的键名转换为驼峰命名法
    if (isPlainObject(data)) {
      return mapKeys(data as object, (value, key) => this.mapKey(key, style)) as T
    }

    // 返回传入数据作为指定类型的对象
    return data as T
  }

  /**
   * 转换key字符串
   * @param key 要转换的key字符串
   * @param style 转换风格
   * @returns 转换后的key字符串
   */
  protected static mapKey(key: string, style: ObjectMapperStyle) {
    switch (style) {
      case ObjectMapperStyle.CamelCase:
        return camelCase(key)
      case ObjectMapperStyle.SnakeCase:
        return snakeCase(key)
      default:
        return key
    }
  }
}
